package shopping

import (
	"errors"
	"fmt"
	"dhfshop/models"
	"dhfshop/models/org"
	"strings"
	"time"
	//"dhfshop/utils/helper"
	"dhfshop/models/consts"
	//"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
)

/* 配货通知单 */
type ShipNotify struct {
    ShipNotifyId int64  `orm:"column(delivery_notify_id);pk;auto" json:"delivery_notify_id" form:"delivery_notify_id"`  /*  */
	PartnerId    int    `orm:"column(partner_id);index" json:"partner_id" form:"partner_id" valid:"Required"`
	StoreId      int    `orm:"column(store_id);index" json:"store_id" form:"store_id"`                  /* 多店铺 */
    WarehouseId  int64     `orm:"column(warehouse_id)" json:"warehouse_id" form:"warehouse_id"`           //目标仓库id
	OrderId      int64     `orm:"column(order_id);index" json:"-" form:"-"`                                /*来源订单号*/    
	OrderIdStr   string    `orm:"-" json:"order_id" form:"order_id"`    
	CreatorUser  *org.User `orm:"rel(fk);column(creator_id);on_delete(do_nothing)" json:"-" form:"-"`     /* 交易录入者*/
    CreatorId    int64     `orm:"-" json:"creator_id" form:"-"`         
	/************ 时间节点信息 ******************************/	
    CreatedAt        time.Time   `orm:"auto_now_add;column(created_at);type(datetime)" json:"-" form:"-"`   /* 创建时间 */
	CreatedAtStr     string      `orm:"-" json:"created_at" form:"-"`
	UpdatedAt        time.Time   `orm:"auto_now;column(updated_at);type(datetime)" json:"-" form:"-"` 
	UpdatedAtStr     string      `orm:"-" json:"updated_at" form:"-"`
	Status           string      `orm:"column(status)" json:"status" form:"status"`    
	/******************* crm信息 ******************************/	
    ReceiverCountry  string      `orm:"column(receiver_country);null" json:"receiver_country" form:"receiver_country"` 
	ReceiverState    string      `orm:"column(receiver_state);null" json:"receiver_state" form:"receiver_state"`         
    ReceiverCity     string      `orm:"column(receiver_city);size(256);null" json:"receiver_city" form:"receiver_city"`
    ReceiverDistrict string      `orm:"column(receiver_district);size(256);null" json:"receiver_district" form:"receiver_district"`
	ReceiverAddress  string      `orm:"column(receiver_address);size(256);null" json:"receiver_address" form:"receiver_address"`
    ReceiverMobile   string      `orm:"column(receiver_mobile);size(32);null" json:"receiver_mobile" form:"receiver_mobile"`            
	ReceiverName     string      `orm:"column(receiver_name);null" json:"receiver_name" form:"receiver_name"` 
    ReceiverPhone    string      `orm:"column(receiver_phone);null" json:"receiver_phone" form:"receiver_phone"`                             
    ReceiverZip      string      `orm:"column(receiver_zip);null" json:"receiver_zip" form:"receiver_zip"`  
	/****************** 财务信息 ************************/
    Payment          float32     `orm:"column(payment);digits(12);decimals(2)" json:"payment" form:"payment"`  /*交易实付金额*/
	/******************物流信息*******************************/
	ShippingType     string      `orm:"column(shipping_type);size(64);null" json:"shipping_type" form:"shipping_type"` /*交易物流方式名称*/
    LogisticsNo      string      `orm:"column(logistics_no);size(64);null" json:"logistics_no" form:"logistics_no"`  /*运单号*/
	IsProtect        bool        `orm:"column(is_protect)" json:"is_protect" form:"is_protect"`          /*物流配送是否保价*/
	ReceiverAt       time.Time   `orm:"column(receiver_at);type(datetime);null" json:"-" form:"-"`        /*要求到货时间*/                
	ReceiverAtStr    string      `orm:"-" json:"receiver_at" form:"receiver_at"`                        /* 输入输出 */
    /**********************发票与其它*********************************/	
	HasInvoice       bool       `orm:"column(has_invoice)" json:"has_invoice" form:"has_invoice"` /*是否开发票。可选值：true(开),false(不开)。默认不开*/
	InvoiceType      string     `orm:"column(invoice_type);size(32);null" json:"invoice_type" form:"invoice_type"`     /*发票类型*/
	InvoiceTitle     string     `orm:"column(invoice_title);size(64);null" json:"invoice_title" form:"invoice_title"`   /*发票标题*/
	InvoiceDesc      string     `orm:"column(invoice_desc);size(64);null" json:"invoice_desc" form:"invoice_desc"`      /*发票内容*/
	ShipItems       []*ShipItem `orm:"reverse(many)" json:"ship_items"`                        
	ShipItemsJson    string     `orm:"-" json:"-" form:"ship_items"`                        
	Remark           string     `orm:"column(remark);null" json:"remark" form:"remark"` 
}

/* 配货通知单商品明细 */
type ShipItem struct {
	PartnerId     int         `orm:"column(partner_id);index" json:"partner_id" form:"partner_id" valid:"Required"`
    ShipItemId    int64       `orm:"column(ship_item_id);pk;auto" json:"delivery_item_id"`        
	ShipNotify    *ShipNotify `orm:"column(ship_notify_id);rel(fk);on_delete(cascade)" json:"-"`  
	ShipNotifyId  string      `orm:"-" json:"ship_notify_id"`                          
    Num           int32       `orm:"column(num);null" json:"num"`               /* 商品总数量*/
	TotalPayment  float32     `orm:"column(total_payment);digits(12);decimals(2)" json:"total_payment"`  /* 实付金额 */
    ItemId        int64       `orm:"column(item_id)" json:"item_id,string"`     /* 商品ID */
	Title         string      `orm:"column(title);size(128);null" json:"title"` /* 商品标题 */
    SkuId         int64       `orm:"column(sku_id)" json:"sku_id,string"`       /* 商品的最小库存单位Sku的id */
	SkuProperties string      `orm:"column(sku_properties);size(32);null" json:"sku_properties"`  /* SKU的值。如：机身颜色:黑色;手机套餐:官方标配 */
	Price         float32     `orm:"column(price);digits(12);decimals(2)" json:"price"`  /* 实付单价 */
	Remark        string      `orm:"column(remark);null" json:"remark" form:"remark"`    /* 备注 */
}

func init() {
    orm.RegisterModel(new(ShipItem),new(ShipNotify))   
}

func AddShipNotify(m *ShipNotify) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}

func AddShipItem(m *ShipItem) (id int64, err error) {
	o := models.GetDefaultDB()
	id, err = o.Insert(m)
	return
}

func AddMultiShipItems(list []*ShipItem) (err error) {
    o := models.GetDefaultDB()
    size := len(list)
	if size > 1 {
	    _, err = o.InsertMulti(size, list) 
	}else{
	   _, err = o.Insert(list[0])
	}	
	return
}

func GetShipNotifyById(id int64) (v *ShipNotify, err error) {
	o := models.GetDefaultDB()
	v = &ShipNotify{ShipNotifyId: id}
	if err = o.Read(v); err == nil {
	    o.LoadRelated(v, "ShipItems")
		v.OrderIdStr = fmt.Sprintf("%d", v.OrderId)
		for _, order := range v.ShipItems {
			order.ShipNotify = nil
		}
		return v, nil
	}
	return nil, err
}

func GetShipNotifyStatusById(shipNotifyId string) (string, error) {
	o := models.GetDefaultDB()
    pShipNotify := &ShipNotify{}
	err := o.QueryTable(new(ShipNotify)).Filter("ship_notify_id",shipNotifyId).One(pShipNotify,"status")
	if err != nil {
		return "", err
	}
	return pShipNotify.Status, nil
}

func GetShipItemById(id int64) (v *ShipItem, err error) {
	o := models.GetDefaultDB()
	v = &ShipItem{ShipItemId: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

func GetAllShipNotifys(storeIds []int64,query map[string]string,fields []string,order_by map[string]string,offset int,limit int)([]*ShipNotify,int64,error){
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(ShipNotify))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		if ok := strings.Contains(v, ";"); ok {
		    valueArr := strings.Split(v, ";")
			qs = qs.Filter(k, valueArr)
		}else{
		    qs = qs.Filter(k, v)
		}	
	}
	if len(storeIds) > 0 {
        qs = qs.Filter("store_id__in", storeIds)
    }
	cnt, err := qs.Count()
	// order by:
	var sortFields []string
	for k, v := range order_by {
		orderby := ""
		if v == "desc" {
			orderby = "-" + k
		} else if v == "asc" {
			orderby = k
		} else {
			return nil, 0, errors.New("Error: Invalid order. Must be either [asc|desc]")
		}
		sortFields = append(sortFields, orderby)
	}
	qs = qs.OrderBy(sortFields...)
	var lists []*ShipNotify
	if _, err = qs.Limit(limit, offset).All(&lists, fields...); err == nil {
	    for _, delivery := range lists {
		    delivery.CreatorId = delivery.CreatorUser.UserId
            delivery.CreatedAtStr = delivery.CreatedAt.Format(consts.DATETIME_FORMAT)
			delivery.UpdatedAtStr = delivery.UpdatedAt.Format(consts.DATETIME_FORMAT)
			delivery.ReceiverAtStr = delivery.ReceiverAt.Format(consts.DATETIME_FORMAT)
			delivery.OrderIdStr = fmt.Sprintf("%d", delivery.OrderId)
			o.LoadRelated(delivery, "ShipItems")
			for _, item := range delivery.ShipItems {
				item.ShipNotifyId = fmt.Sprintf("%d", item.ShipNotify.ShipNotifyId)
				item.ShipNotify = nil
			}
	    }
		return lists, cnt, nil
	}
	return nil, 0, err
}
	
func UpdateShipNotifyById(m *ShipNotify, param ...string) (err error) {
	o := models.GetDefaultDB()
	v := ShipNotify{ShipNotifyId: m.ShipNotifyId}
	if err = o.Read(&v); err == nil {
		_, err = o.Update(m, param...)
		return
	}
	return
}

func UpdateShipNotifyStatusById(shipNotifyId int64, nextState string) (err error) {
	o := models.GetDefaultDB()
	v := &ShipNotify{ShipNotifyId:shipNotifyId,Status:nextState}
	_, err = o.Update(v,"status")
	if err != nil {
		return
	}
	return
}

func UpdateShipItemById(m *ShipItem, k ...string) (err error) {
	o := models.GetDefaultDB()
	v := ShipItem{ShipItemId: m.ShipItemId}
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Update(m, k...); err == nil {
			fmt.Println("Number of records updated in database:", num)
		}
	}
	return
}
func DeleteShipNotify(id int64) (err error) {
    o := models.GetDefaultDB()
	v := ShipNotify{ShipNotifyId: id}
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Delete(&v); err == nil {
			fmt.Println("Number of records deleted in database:", num)
		}
	}
	return
}

//company_id,tid,status
func GetShipItemByOrderId(query map[string]string)(map[int64]int32, error){
	mapSkuNumber := make(map[int64]int32)
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(ShipNotify))
	for k, v := range query {
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	var lists []*ShipNotify
	_, err := qs.All(&lists)
	if err == nil {
	    for _, delivery := range lists {
		    o.LoadRelated(delivery, "ShipItems")
			for _, item := range delivery.ShipItems {
				if value, exist := mapSkuNumber[item.SkuId]; exist {
			        mapSkuNumber[item.SkuId] = value + item.Num
			    } else {
			        mapSkuNumber[item.SkuId] = item.Num
			    }
		    }
	    }
		return mapSkuNumber, nil
	}
	return mapSkuNumber, err
}

func GetShipItemByStatus(companyId int, tid int64,statusStr string)(map[int64]int32, error){
	statusArr := strings.Split(statusStr, ",")
	mapSkuNumber := make(map[int64]int32)
	o := models.GetDefaultDB()
	qs := o.QueryTable(new(ShipNotify))
	qs = qs.Filter("status__in", statusArr).Filter("company_id", companyId).Filter("tid", tid)
	var lists []*ShipNotify
	_, err := qs.All(&lists)
	if err == nil {
	    for _, delivery := range lists {
		    o.LoadRelated(delivery, "DeliveryItems")
			for _, item := range delivery.ShipItems {
				if value, exist := mapSkuNumber[item.SkuId]; exist {
			        mapSkuNumber[item.SkuId] = value + item.Num
			    } else {
			        mapSkuNumber[item.SkuId] = item.Num
			    }
		    }
	    }
		return mapSkuNumber, nil
	}
	return mapSkuNumber, err
}

